package com.calvin.study.threadsafe.lock.viewlock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditonDemo02 {

	public static void main(String[] args) {
		// 线程A\B\C操纵资源类
		Data data = new Data();// 资源类

		for (int i = 0, len = 2; i < len; i++) {
			new Thread(() -> {
				data.methodA();
			}, "A").start();
			
			new Thread(() -> {
				data.methodB();
			}, "B").start();
			
			new Thread(() -> {
				data.methodC();
			}, "C").start();
		}

//		new Thread(() -> {
//			for (int i = 0, len = 2; i < len; i++) {
//				data.methodA();
//			}
//		}, "A").start();
//
//		new Thread(() -> {
//			for (int i = 0, len = 2; i < len; i++) {
//				data.methodB();
//			}
//		}, "B").start();
//
//		new Thread(() -> {
//			for (int i = 0, len = 2; i < len; i++) {
//				data.methodC();
//			}
//		}, "C").start();
	}

}

class Data {
	// 执行标识，判断该第几个线程执行
	private int num = 1;
	// 显示锁
	private Lock lock = new ReentrantLock();

	Condition cond1 = lock.newCondition();
	Condition cond2 = lock.newCondition();
	Condition cond3 = lock.newCondition();

	public void methodA() {
		lock.lock();
		try {
			while (num != 1) {// 如果不该A执行，则轮到B执行
				cond1.await();
			}
			for (int i = 1; i <= 5; i++) {
				System.out.println("当前线程:" + Thread.currentThread().getName() + "\t value=>" + i);
			}
			// 设置执行的调用标识
			num = 2;
			// 唤醒指定的线程
			cond2.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void methodB() {
		lock.lock();
		try {
			while (num != 2) {
				cond2.await();
			}
			for (int i = 1; i <= 10; i++) {
				System.out.println("当前线程:" + Thread.currentThread().getName() + "\t value=>" + i);
			}
			num = 3;
			cond3.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void methodC() {
		lock.lock();
		try {
			while (num != 3) {
				cond3.await();
			}
			for (int i = 1; i <= 15; i++) {
				System.out.println("当前线程:" + Thread.currentThread().getName() + "\t value=>" + i);
			}
			num = 1;
			cond1.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}